#include "electronicscaleintervalrate.h"
#include "electronicscaletool.h"
#include <QDateTime>

ElectronicScaleIntervalRate::ElectronicScaleIntervalRate(QObject *parent)
    : QObject(parent)
{

}

ElectronicScaleIntervalRate::~ElectronicScaleIntervalRate()
{

}

void ElectronicScaleIntervalRate::setInterval(quint32 second)
{
    m_interval = second;
}

quint32 ElectronicScaleIntervalRate::getInterval() const
{
    return m_interval;
}

bool ElectronicScaleIntervalRate::exportIntervalRateToXlsx(const QString &path)
{
    return ElectronicScaleTool::exportIntervalRateToXlsx(path, m_rates);
}

bool ElectronicScaleIntervalRate::importIntervalRateFromXlsx(const QString &path)
{
    return ElectronicScaleTool::importIntervalRateFromXlsx(path, m_rates);
}

electronicscale::IntervalRate ElectronicScaleIntervalRate::getIntervalRate() const
{
    return m_rate;
}

bool ElectronicScaleIntervalRate::setIntervalRates(QList<electronicscale::IntervalRate> &rates)
{
    if (m_isStart)
        return false;

    m_rates = rates;
    return true;
}

QList<electronicscale::IntervalRate> ElectronicScaleIntervalRate::getIntervalRates() const
{
    return m_rates;
}

void ElectronicScaleIntervalRate::addSample(electronicscale::Sample sample)
{
    m_samples << sample;

    if (!m_isGetFirstData) // 第一个点
    {
        m_prevSample = sample;

        m_rate.time = sample.time;
        m_rate.rate.value = 0; // 第一个点的速度为0
        m_rate.rate.unit = ElectronicScaleTool::getMatchup(sample.weight.unit);
        m_rate.rate.currentWeight = sample.weight.value;
        m_rates << m_rate;

        m_isCalculate = true; // 为了上传第一个点，这里设置为true
    }
}

void ElectronicScaleIntervalRate::start()
{
    m_isGetFirstData = false;
    m_isCalculate = false;
    m_isStart = true;

    m_samples.clear();
    m_rates.clear();
}

void ElectronicScaleIntervalRate::stop()
{
    m_isStart = false;
}

bool ElectronicScaleIntervalRate::isStart() const
{
    return m_isStart;
}

bool ElectronicScaleIntervalRate::isCalculate() const
{
    return m_isCalculate;
}

electronicscale::IntervalRate ElectronicScaleIntervalRate::calculate()
{
    m_isCalculate = false;

    if (!m_isGetFirstData)
    {
        m_isGetFirstData = true;
        return m_rate;
    }

    electronicscale::Sample calculatePoint;
    calculatePoint = ElectronicScaleTool::findWeight(m_rate.time, m_samples);
    m_rate.rate.unit = ElectronicScaleTool::getMatchup(calculatePoint.weight.unit);
    m_rate.rate.value = (calculatePoint.weight.value - m_prevSample.weight.value) / m_interval * 3600;
    m_rate.rate.currentWeight = calculatePoint.weight.value;
    m_rates << m_rate;
    m_prevSample = calculatePoint;

    m_samples.clear();

    return m_rate;
}

electronicscale::IntervalRate ElectronicScaleIntervalRate::stopToCalculate()
{
    m_isCalculate = false;

    if (m_samples.size())
    {
        double deltaTime = (double)(m_samples.last().time - m_prevSample.time) / 1000.0;
        m_rate.rate.unit = ElectronicScaleTool::getMatchup(m_prevSample.weight.unit);
        m_rate.time = m_prevSample.time;
        m_rate.rate.value = (m_samples.last().weight.value - m_prevSample.weight.value) / deltaTime * 3600;
        m_rate.rate.currentWeight = m_samples.last().weight.value;
        m_rates << m_rate;
        m_prevSample = m_samples.last();

        m_samples.clear();
    }
    return m_rate;
}

QList<electronicscale::IntervalRate> ElectronicScaleIntervalRate::calculate(const QList<electronicscale::Sample> &samples, quint32 interval)
{
    QList<electronicscale::IntervalRate> rates;
    electronicscale::IntervalRate rate;
    electronicscale::Sample prevSample = samples.at(0);
    rate.rate.unit = ElectronicScaleTool::getMatchup(prevSample.weight.unit);
    electronicscale::Sample prevRateSample = samples.at(0); // 第一个速度点
    electronicscale::Sample nextRateSample; // 下一个速度点
    nextRateSample.time = prevRateSample.time + interval * 1000;
    // 第一个速度点为0
    rate.time = samples.at(0).time;
    rate.rate.value = 0;
    rate.rate.currentWeight = samples.at(0).weight.value;
    rates << rate;
    foreach (auto s, samples)
    {
        if (s.time >= nextRateSample.time)
        {
            electronicscale::Sample calculatePoint;
            calculatePoint = ElectronicScaleTool::getLinearWeight(nextRateSample.time, prevSample, s);
            rate.rate.unit = ElectronicScaleTool::getMatchup(calculatePoint.weight.unit);
            rate.time = nextRateSample.time;
            rate.rate.currentWeight = calculatePoint.weight.value;
            rate.rate.value = (calculatePoint.weight.value - prevRateSample.weight.value) / interval * 3600;
            rates << rate;
            prevRateSample = calculatePoint;
            nextRateSample.time = prevRateSample.time + interval * 1000;
        }
        prevSample = s;
    }
    // 计算最后一段的速度
    if (prevRateSample.time != samples.last().time)
    {
        rate.rate.unit = ElectronicScaleTool::getMatchup(prevRateSample.weight.unit);
        rate.time = samples.last().time;
        rate.rate.currentWeight = samples.last().weight.value;
        double delta = samples.last().weight.value - prevRateSample.weight.value;
        double time = double(samples.last().time - prevRateSample.time) / 1000.0;
        rate.rate.value = delta / time * 3600;
        rates << rate;
    }
    return rates;
}

void ElectronicScaleIntervalRate::onTimeout()
{
    m_intervalCnt++;
    if (m_intervalCnt >= m_interval)
    {
        m_intervalCnt = 0;
        // 计算瞬时流速
        // 等到下一个数据出来再算，因为这个时间点极有可能在相邻的2个采样点中间，而最新的采样点还没出来
        m_rate.time = QDateTime::currentMSecsSinceEpoch();
        m_isCalculate = true;
    }
}
